package com.txl.lzxl.nianxing;

import android.animation.FloatEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.OvershootInterpolator;

/**
 * Created by feq on 2016/11/28.
 */

public class GooView extends View {

    private Paint mPaint;
    PointF mStickCenter = new PointF(500f, 500f);
    private float mStickRadius = 20f;

    PointF mDragCenter = new PointF(500f, 500f);
    private float mDragRadius = 25f;
    PointF[] mDragPoints;
    PointF[] mStickPoints;
    PointF mControlPoint;
    private int mStatusBarHeight;
    private boolean mIsOutOfRange = false;//没有断开状态
    private boolean mIsDistance = false;//是否消失

    public GooView(Context context) {
        super(context);
        init();
    }

    public GooView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
    }

    public GooView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //计算固定圆的半径
        float tempStickRadius = computeStickRadius();
        //计算这些变量
        float yOffset = mStickCenter.y - mDragCenter.y;
        float xOffset = mStickCenter.x - mDragCenter.x;
        Double linek = null;
        if (xOffset != 0) {
            linek = (double) (yOffset / xOffset);
        }
        //获取拖拽圆的附着点
        mDragPoints = GeometryUtil.getIntersectionPoints(mDragCenter, mDragRadius, linek);
        mStickPoints = GeometryUtil.getIntersectionPoints(mStickCenter, tempStickRadius, linek);
        //获取控制点坐标
        mControlPoint = GeometryUtil.getMiddlePoint(mDragCenter, mStickCenter);


        canvas.save();//保存状态
        //绘制之前将画布向上平移状态栏的高度
        canvas.translate(0, -mStatusBarHeight);

        //绘制最大范围
//        canvas.drawCircle(mStickCenter.x, mStickCenter.y, farestDistance, mPaint);

        if (!mIsDistance) {//没有消失才绘制
            if (!mIsOutOfRange) {
                Path path = new Path();
                //跳到某个点
                path.moveTo(mStickPoints[0].x, mStickPoints[0].y);
                //点1到点2画曲线
                path.quadTo(mControlPoint.x, mControlPoint.y, mDragPoints[0].x, mDragPoints[0].y);
                //点2 到  点3  直线连接
                path.lineTo(mDragPoints[1].x, mDragPoints[1].y);
                path.quadTo(mControlPoint.x, mControlPoint.y, mStickPoints[1].x, mStickPoints[1].y);
                path.close();
                canvas.drawPath(path, mPaint);
                //绘制固定圆
                canvas.drawCircle(mStickCenter.x, mStickCenter.y, tempStickRadius, mPaint);
            }
            //绘制拖拽圆
            canvas.drawCircle(mDragCenter.x, mDragCenter.y, mDragRadius, mPaint);
        }
        canvas.restore();//恢复到上一次的状态
    }

    float farestDistance = 80f;

    /**
     * 根据圆形的间距，计算实时的固定圆半径
     *
     * @return
     */
    private float computeStickRadius() {
        float distanceBetween2Points = GeometryUtil.getDistanceBetween2Points(mDragCenter, mStickCenter);
        distanceBetween2Points = Math.min(distanceBetween2Points, farestDistance);

        //0-80

        float percent = distanceBetween2Points / farestDistance;

        //0.0--1.o

        //12f --3f


        return evaluator.evaluate(percent, mStickRadius, mStickRadius * 0.25f);
    }

    FloatEvaluator evaluator = new FloatEvaluator();

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mIsOutOfRange = false;
                mIsDistance = false;
                break;
            case MotionEvent.ACTION_MOVE:
                float x = event.getRawX();
                float y = event.getRawY();
                updataDragCenter(x, y);

                float d = GeometryUtil.getDistanceBetween2Points(mDragCenter, mStickCenter);
                if (d > farestDistance) {
                    mIsOutOfRange = false;
                    invalidate();
                }

                break;
            case MotionEvent.ACTION_UP:
                if (mIsOutOfRange) {
                    float dis = GeometryUtil.getDistanceBetween2Points(mDragCenter, mStickCenter);
                    if (dis > farestDistance) {
                        mIsDistance = false;
                        invalidate();
                    } else {
                        updataDragCenter(mStickCenter.x, mStickCenter.y);
                    }
                } else {
                    ValueAnimator animator = ValueAnimator.ofFloat(1.0f);
                    final PointF startPoint = new PointF(mDragCenter.x, mDragCenter.y);
                    animator.setInterpolator(new OvershootInterpolator());
                    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                        @Override
                        public void onAnimationUpdate(ValueAnimator valueAnimator) {
                            float animatedFraction = valueAnimator.getAnimatedFraction();
                            PointF pointByPercent = GeometryUtil.getPointByPercent(startPoint, mStickCenter, animatedFraction);
                            //让新的点生效
                            updataDragCenter(pointByPercent.x, pointByPercent.y);
                        }
                    });
                    animator.setDuration(500);
                    animator.start();
                }
                break;
        }
        return true;
    }

    private void updataDragCenter(float x, float y) {
        mDragCenter.set(x, y);
        invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mStatusBarHeight = Utils.getStatusBarHeight(this);
    }
}
